package com.hp.gxw.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hp.gxw.config.DataBaseConfig;
import com.hp.gxw.constant.LayTableR;
import com.hp.gxw.constant.R;
import com.hp.gxw.constant.TypeEnum;
import com.hp.gxw.entity.*;
import com.hp.gxw.exception.BusinessException;
import com.hp.gxw.mapper.SaleOrderProcessMapper;
import com.hp.gxw.service.*;
import com.hp.gxw.u8.EFWebService;
import com.hp.gxw.u8.U8ApiUtils;
import com.hp.gxw.u8.U8WebXMLResponseU8WebXMLResult;
import com.hp.gxw.u8.dto.*;
import com.hp.gxw.u8.xml.DispatchListsXml;
import com.hp.gxw.u8.xml.SomainXml;
import com.hp.gxw.utils.DateUtil;
import com.hp.gxw.utils.ShiroUtil;
import org.apache.axis.message.MessageElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author huangping
 * @since 2023-10-17
 */
@Service
public class SaleOrderProcessServiceImpl extends ServiceImpl<SaleOrderProcessMapper, SaleOrderProcess> implements ISaleOrderProcessService {

    @Autowired
    private ISaleOrderDetailsService iSaleOrderDetailsService;

    @Autowired
    @Lazy
    private ISaleOrderService iSaleOrderService;

    @Autowired
    @Lazy
    private ISettlementOrderDetailsService iSettlementOrderDetailsService;

    @Autowired
    private EFWebService eFWebServiceLocator;

    @Autowired
    private U8ApiUtils u8ApiUtils;

    @Resource
    private SaleOrderProcessMapper saleOrderProcessMapper;

    @Autowired
    private ISettleOrderMasterNewService iSettleOrderMasterNewService;

    @Autowired
    private ISettleOrderDetailNewService iSettleOrderDetailNewService;

    @Autowired
    private IProcessPriceOrderService iProcessPriceOrderService;

    @Value("${u8client.serviceId}")
    private String serviceId;

    @Value("${u8client.dispatchWarehouse}")
    private String dispatchWarehouse;

    @Value("${u8client.dispatchItaxrate}")
    private String dispatchItaxrate;

    @Value("${u8client.environment}")
    private String environment;

    @Override
    public LayTableR processInfo(Integer page, Integer limit, String detailsId) {
        QueryWrapper<SaleOrderProcess> queryWrapper = Wrappers.query();
        queryWrapper.eq("a.details_id", detailsId);
        List list = saleOrderProcessMapper.processInfo(new Page(page, limit), queryWrapper);
        return LayTableR.result(0, list.size(), list);
    }

    @Override
    @Transactional
    public void priceSet(SaleOrderDetails orderDetails,List<SaleOrderProcess> processList) {
        SaleOrder saleOrder = iSaleOrderService.getById(orderDetails.getMasterId());
        if(TypeEnum.by_process.getCode().equals(orderDetails.getCzjslx())){
            //按数量
            for (SaleOrderProcess saleOrderProcess : processList) {
                saleOrderProcess.setAmount(saleOrderProcess.getIoritaxcost().multiply(orderDetails.getQty()));
            }
            BigDecimal amount = processList.stream().map(e -> e.getAmount()).collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
            orderDetails.setAmount(amount);
        }else if(TypeEnum.by_cbatch.getCode().equals(orderDetails.getCzjslx())){
            //按批次
        }else if(TypeEnum.by_test_time.getCode().equals(orderDetails.getCzjslx()) || TypeEnum.by_machine_time.getCode().equals(orderDetails.getCzjslx())){
            //按时间
            for(SaleOrderProcess saleOrderProcess : processList){
                if(saleOrderProcess.getExpectHours() == null || saleOrderProcess.getExpectHours().compareTo(BigDecimal.ZERO) <= 0){
                    throw new BusinessException("工序【"+saleOrderProcess.getOrderProcessName()+"】标准工时不能为空或小于等于0");
                }
                saleOrderProcess.setAmount(saleOrderProcess.getIoritaxcost().multiply(saleOrderProcess.getExpectHours()).multiply(orderDetails.getQty()));
            }
            BigDecimal amount = processList.stream().map(e -> e.getAmount()).collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
            orderDetails.setAmount(amount);
        }
        updateBatchById(processList);
        orderDetails.setCompletFlag(true);
        iSaleOrderDetailsService.updateById(orderDetails);
        long count = iSaleOrderDetailsService.count(new LambdaQueryWrapper<SaleOrderDetails>()
                        .ne(SaleOrderDetails::getId, orderDetails.getId())
                        .eq(SaleOrderDetails::getMasterId, orderDetails.getMasterId())
                        .eq(SaleOrderDetails::getCompletFlag, false));
        if(count == 0){
            saleOrder.setFixStatus(true);
        }
        //判断是否生成工序价格表
        if (orderDetails.isMark()){
            List<ProcessPriceOrder> processPriceOrderList = new ArrayList<>();
            for (SaleOrderProcess orderProcess : processList) {
                ProcessPriceOrder priceOrder = new ProcessPriceOrder();
                priceOrder.setId(orderProcess.getPriceId());
                priceOrder.setCustomerId(saleOrder.getCustomerCode());
                priceOrder.setProductId(orderDetails.getCinvcode());
                priceOrder.setType(orderDetails.getType());
                priceOrder.setPricingMethod(orderDetails.getCzjslx());
                priceOrder.setOrderProcessCode(orderProcess.getOrderProcess());
                priceOrder.setExpectHours(orderProcess.getExpectHours());
                priceOrder.setOrderPrice(orderProcess.getIoritaxcost());
                priceOrder.setCreateUser(ShiroUtil.getUserId());
                priceOrder.setCreateTime(new Date());
                processPriceOrderList.add(priceOrder);
            }
            iProcessPriceOrderService.saveOrUpdateBatch(processPriceOrderList);
        }
        //生成U8销售订单
        try {
            List<SaleOrderDetails> sodetailsParameterList = new ArrayList<>();
            sodetailsParameterList.add(orderDetails);
            saleOrder.setDetailsList(sodetailsParameterList);
            R result = generateU8somain(saleOrder);
            if("500".equals(result.get("code").toString())){
                throw new BusinessException(result.get("msg").toString());
            }
            iSaleOrderService.updateById(saleOrder);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("生成U8销售订单时发生异常");
        }
    }

    @Override
    @Transactional
    public void settlementPriceSetNew(String settleDetailId, List<SettlementOrderProcess> processList, String type) {
//        //查询结算单detail
//        SettlementOrderDetails settlementOrderDetail = iSettlementOrderDetailsService.getOne(Wrappers.lambdaQuery(SettlementOrderDetails.class).eq(SettlementOrderDetails::getId, settleDetailId));
//        if (settlementOrderDetail == null) {
//            throw new RuntimeException();
//        }
//        //获取销售订单detail
//        SaleOrderDetails saleOrderDetail = iSaleOrderDetailsService.getOne(Wrappers.lambdaQuery(SaleOrderDetails.class).eq(SaleOrderDetails::getId, settlementOrderDetail.getDetailId()));
//        if (saleOrderDetail == null){
//            throw new RuntimeException();
//        }
//        //获取销售订单工序
//        List<SaleOrderProcess> list = list(Wrappers.lambdaQuery(SaleOrderProcess.class).eq(SaleOrderProcess::getDetailsId, saleOrderDetail.getMesId()));
//        if (list.isEmpty()){
//            throw new RuntimeException();
//        }
//        //计算必须从第一道工序开始，排序
//        list = list.stream().sorted(Comparator.comparing(SaleOrderProcess::getSerialNumber)).collect(Collectors.toList());
//        //结算单工序 ，合格不合格数量
//        Map<Integer, SettlementOrderProcess> orderProcessMap = processList.stream().collect(Collectors.toMap(SettlementOrderProcess::getSerialNumber, obj -> obj));
//        //计算
//        for (SaleOrderProcess orderProcess : list) {
//            BigDecimal price = BigDecimal.ZERO;
//            //计算结算方式，算出结算单价
//            if (orderProcess.getPricingMethod().equals(TypeEnum.js.getCode())){
//                price = saleOrderDetail.getQty().multiply(orderProcess.getExpectHours()).multiply(orderProcess.getSettlementcost());
//            }
//            if (orderProcess.getPricingMethod().equals(TypeEnum.jj.getCode())){
//                price = saleOrderDetail.getQty().multiply(orderProcess.getSettlementcost());
//            }
//            if (orderProcess.getPricingMethod().equals(TypeEnum.ap.getCode())){
//                price = orderProcess.getSettlementcost();
//            }
//            orderProcess.setJjfsje(price);
//            orderProcess.setSettlementcost(price);
//            //整单结算
//            if (type.equals(TypeEnum.zd.getCode())){
//                //获取结算第一道工序
//                SettlementOrderProcess settlementOrderProcess = orderProcessMap.get(list.get(0).getSerialNumber());
//                //结算数量
//                BigDecimal qty = settlementOrderProcess.getQty().add(settlementOrderProcess.getUnQty());
//                orderProcess.setSettlementQty(qty);
//                //结算价格 = 结算数量 * 结算单价
//                BigDecimal sum = qty.multiply(price);
//                orderProcess.setSettlementamount(sum);
//            }
//            //良率结算
//            if (type.equals(TypeEnum.lv.getCode())){
//                //获取最后一道工序的良品数作为每单的结算数量
//                SettlementOrderProcess settlementOrderProcess = orderProcessMap.get(list.get(list.size()-1).getSerialNumber());
//                //结算数量
//                BigDecimal qty = settlementOrderProcess.getQty();
//                orderProcess.setSettlementQty(qty);
//                //结算价格 = 结算数量 * 结算单价
//                BigDecimal sum = qty.multiply(price);
//                orderProcess.setSettlementamount(sum);
//            }
//        }
//        int seQty = list.stream().mapToInt(obj -> obj.getSettlementQty().intValue()).sum();
//        double seSum = list.stream().mapToDouble(obj -> obj.getSettlementQty().setScale(3, RoundingMode.DOWN).doubleValue()).sum();
//        settlementOrderDetail.setSettlementQty(BigDecimal.valueOf(seQty));
//
//        //计算折扣后的金额
//        if (null != settlementOrderDetail.getZkv()){
//            double zlv = settlementOrderDetail.getZkv().divide(BigDecimal.valueOf(100)).setScale(3, RoundingMode.DOWN).doubleValue();
//            seSum = seSum * zlv;
//        }
//        settlementOrderDetail.setSettlementAmount(BigDecimal.valueOf(seSum).setScale(3, RoundingMode.DOWN));
//
//        saleOrderDetail.setSettlementQty(saleOrderDetail.getSettlementQty().add(settlementOrderDetail.getSettlementQty()));
//        saleOrderDetail.setSettlementAmount(saleOrderDetail.getSettlementAmount().add(settlementOrderDetail.getSettlementAmount()));
//        //更新指定表
//        settlementOrderDetail.setCompletFlag(true);
//        saleOrderDetail.setCompletFlag(true);
//        //变更销售订单工序
//        updateBatchById(list);
//        //变更销售订单表体
//        iSaleOrderDetailsService.updateById(saleOrderDetail);
//        //变更结算单表体
//        iSettlementOrderDetailsService.updateById(settlementOrderDetail);
//
//        //记录结算单加工工序对应的订单工序结算单价
//        List<SettlementProcess> settlementProcessList = new ArrayList<>();
//        for (SettlementOrderProcess saleOrderProcess : processList) {
//            SettlementProcess settlementProcess = new SettlementProcess();
//            settlementProcess.setSerialNumber(saleOrderProcess.getSerialNumber());
//            settlementProcess.setOrderProcess(saleOrderProcess.getOrderProcess());
//            settlementProcess.setOrderProcessName(saleOrderProcess.getOrderProcessName());
//            settlementProcess.setSettlementcost(saleOrderProcess.getSettlementCost());
//            settlementProcess.setDetailsId(settleDetailId);
//            settlementProcessList.add(settlementProcess);
//        }
//        if(!settlementProcessList.isEmpty()){
//            iSettlementProcessService.remove(new LambdaQueryWrapper<SettlementProcess>().eq(SettlementProcess::getDetailsId,settleDetailId));
//            iSettlementProcessService.saveBatch(settlementProcessList);
//        }
//
//        //判断销售订单是否全部结算完毕
//        long count = iSaleOrderDetailsService.count(Wrappers.lambdaQuery(SaleOrderDetails.class).eq(SaleOrderDetails::getCompletFlag, false));
//        if(count == 0){
//            iSaleOrderService.update(Wrappers.lambdaUpdate(SaleOrder.class).set(SaleOrder::getStatus,true).eq(SaleOrder::getId,saleOrderDetail.getMasterId()));
//        }
//        //判断结算订单是否全部结算完毕
//        long count1 = iSettlementOrderDetailsService.count(Wrappers.lambdaQuery(SettlementOrderDetails.class).eq(SettlementOrderDetails::getCompletFlag, false));
//        if(count1 == 0){
//            iSettlementOrderService.update(Wrappers.lambdaUpdate(SettlementOrder.class).set(SettlementOrder::getStatus,true).eq(SettlementOrder::getId,settlementOrderDetail.getMasterId()));
//        }
//        //传递U8 只有在销售订单与结算单都结算完毕才会同步
//        //写入U8发货单
//        //获取结算单
//        SettlementOrder one = iSettlementOrderService.getOne(Wrappers.lambdaQuery(SettlementOrder.class).eq(SettlementOrder::getId, settlementOrderDetail.getMasterId()));
//        if (one == null){
//            throw new RuntimeException();
//        }
//        if (count == 0 && count1 == 0){
//            R result = generateU8dispatchList(one, settlementOrderDetail.getSettlementQty(), settlementOrderDetail.getSettlementAmount());
//            if("500".equals(result.get("code").toString())){
//                throw new RuntimeException();
//            }
//        }
    }

    @Override
    @Transactional
    public void orderSettle(String masterId, String detailsId, SettleOrderMasterNew settleOrderMasterNew) {
        SaleOrder saleOrderMaster = iSaleOrderService.getById(masterId);
        SaleOrderDetails saleOrderDetail = iSaleOrderDetailsService.getById(detailsId);

        //判断结算数量是否超过订单数量
        List<SettleOrderMasterNew> settledList = iSettleOrderMasterNewService.list(Wrappers.lambdaQuery(SettleOrderMasterNew.class)
                .eq(SettleOrderMasterNew::getSaleOrderMasterId, masterId)
                .eq(SettleOrderMasterNew::getSaleOrderDetailId, detailsId));
        BigDecimal sumSettleQty = settledList.stream().map(e -> e.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);
        if(sumSettleQty.add(settleOrderMasterNew.getQty()).compareTo(saleOrderDetail.getQty()) > 0) {
            throw new BusinessException("结算数量不能超过订单数量");
        }
        settleOrderMasterNew.setStockQty(saleOrderDetail.getQty().subtract(sumSettleQty.add(settleOrderMasterNew.getQty())));
        settleOrderMasterNew.setSaleOrderMasterId(saleOrderMaster.getId().toString());
        settleOrderMasterNew.setSaleOrderCode(saleOrderMaster.getOrderNo());
        settleOrderMasterNew.setSaleOrderDetailId(saleOrderDetail.getId().toString());
        settleOrderMasterNew.setCreateUser(ShiroUtil.getUserId().toString());
        settleOrderMasterNew.setCreateTime(new Date());

        List<SettleOrderDetailNew> detailList = settleOrderMasterNew.getDetailList();

        if(TypeEnum.by_process.getCode().equals(saleOrderDetail.getCzjslx())){
            //按数量
            for (SettleOrderDetailNew settlementOrderDetailNew : detailList) {
                settlementOrderDetailNew.setAmount(settlementOrderDetailNew.getIoritaxcost().multiply(settleOrderMasterNew.getQty()));
            }
            BigDecimal amount = detailList.stream().map(e -> e.getAmount()).collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
            settleOrderMasterNew.setAmount(amount);
        }else if(TypeEnum.by_cbatch.getCode().equals(saleOrderDetail.getCzjslx())){
            //按批次
//            settleOrderMasterNew.setAmount(saleOrderDetail.getAmount());
        }else if(TypeEnum.by_test_time.getCode().equals(saleOrderDetail.getCzjslx()) || TypeEnum.by_machine_time.getCode().equals(saleOrderDetail.getCzjslx())){
            //按时间
            for (SettleOrderDetailNew settlementOrderDetailNew : detailList) {
                if(settlementOrderDetailNew.getExpectHours() == null || settlementOrderDetailNew.getExpectHours().compareTo(BigDecimal.ZERO) <= 0){
                    throw new BusinessException("工序【"+settlementOrderDetailNew.getOrderProcessName()+"】标准工时不能为空或小于等于0");
                }
                settlementOrderDetailNew.setAmount(settlementOrderDetailNew.getIoritaxcost().multiply(settlementOrderDetailNew.getExpectHours()).multiply(settleOrderMasterNew.getQty()));
            }
            BigDecimal amount = detailList.stream().map(e -> e.getAmount()).collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
            settleOrderMasterNew.setAmount(amount);
        }
        iSettleOrderMasterNewService.save(settleOrderMasterNew);
        for (SettleOrderDetailNew settlementOrderDetailNew : detailList) {
            settlementOrderDetailNew.setId(null);
            settlementOrderDetailNew.setMasterId(settleOrderMasterNew.getId());
        }
        iSettleOrderDetailNewService.saveBatch(detailList);
        //判断是否生成工序价格表
        if (settleOrderMasterNew.isMark()){
            List<ProcessPriceOrder> processPriceOrderList = new ArrayList<>();
            for (SettleOrderDetailNew aNew : detailList) {
                ProcessPriceOrder priceOrder = new ProcessPriceOrder();
                priceOrder.setId(aNew.getPriceId());
                priceOrder.setCustomerId(saleOrderMaster.getCustomerCode());
                priceOrder.setProductId(saleOrderDetail.getCinvcode());
                priceOrder.setType(saleOrderDetail.getType());
                priceOrder.setPricingMethod(saleOrderDetail.getCzjslx());
                priceOrder.setOrderProcessCode(aNew.getOrderProcess());
                priceOrder.setExpectHours(aNew.getExpectHours());
                priceOrder.setOrderPrice(aNew.getIoritaxcost());
                priceOrder.setCreateUser(ShiroUtil.getUserId());
                priceOrder.setCreateTime(new Date());
                processPriceOrderList.add(priceOrder);
            }
            iProcessPriceOrderService.saveOrUpdateBatch(processPriceOrderList);
        }
        try {
            BigDecimal oldAmount = settleOrderMasterNew.getAmount();
            settleOrderMasterNew.setAmount(settleOrderMasterNew.getAmount().multiply(settleOrderMasterNew.getSettleRate().divide(new BigDecimal(100))));
            R result = generateU8dispatchList(saleOrderMaster, settleOrderMasterNew);
            if("500".equals(result.get("code").toString())){
                throw new BusinessException(result.get("msg").toString());
            }
            settleOrderMasterNew.setAmount(oldAmount);
            iSettleOrderMasterNewService.updateById(settleOrderMasterNew);
        } catch (Exception e) {
            throw new BusinessException("生成U8发货单时发生异常");
        }
    }

    @Override
    @Transactional
    public void settlementPriceSet(String settleDetailId, List<SaleOrderProcess> processList) {
//        updateBatchById(processList);
//        /**记录结算单加工工序对应的订单工序结算单价*/
//        List<SettlementProcess> settlementProcessList = new ArrayList<>();
//        for (SaleOrderProcess saleOrderProcess : processList) {
//            SettlementProcess settlementProcess = new SettlementProcess();
//            settlementProcess.setSerialNumber(saleOrderProcess.getSerialNumber());
//            settlementProcess.setOrderProcess(saleOrderProcess.getOrderProcess());
//            settlementProcess.setOrderProcessName(saleOrderProcess.getOrderProcessName());
//            settlementProcess.setSettlementcost(saleOrderProcess.getSettlementcost());
//            settlementProcess.setDetailsId(settleDetailId);
//            settlementProcessList.add(settlementProcess);
//        }
//        if(settlementProcessList.size() > 0){
//            iSettlementProcessService.remove(new LambdaQueryWrapper<SettlementProcess>().eq(SettlementProcess::getDetailsId,settleDetailId));
//            iSettlementProcessService.saveBatch(settlementProcessList);
//        }
//        SettlementOrderDetails settlementOrderDetails = iSettlementOrderDetailsService.getById(settleDetailId);
//        SettlementOrder settlementOrder = iSettlementOrderService.getById(settlementOrderDetails.getMasterId());
//
//        SaleOrder saleOrder = iSaleOrderService.getOne(new LambdaQueryWrapper<SaleOrder>().eq(SaleOrder::getOrderNo, settlementOrder.getSaleOrderNo()));
//
//        SaleOrderDetails orderDetails = iSaleOrderDetailsService.getOne(new LambdaQueryWrapper<SaleOrderDetails>()
//                .eq(SaleOrderDetails::getMasterId,saleOrder.getId())
//                .eq(SaleOrderDetails::getCinvcode,settlementOrderDetails.getCinvcode()));
//        List<SettlementOrderProcess> settlementOrderProcesses = iSettlementOrderProcessService.list(new LambdaQueryWrapper<SettlementOrderProcess>()
//                .eq(SettlementOrderProcess::getDetailsId, settleDetailId).orderByAsc(SettlementOrderProcess::getSerialNumber));
//        orderDetails.setSettlementQty((orderDetails.getSettlementQty()==null?BigDecimal.ZERO:orderDetails.getSettlementQty()).add(settlementOrderProcesses.get(0).getQty()));
//        BigDecimal sum = BigDecimal.ZERO;
////        Customer customer = iCustomerService.getOne(new LambdaQueryWrapper<Customer>().eq(Customer::getCode, saleOrder.getCustomerCode()));
////        Product product = iProductService.getOne(new LambdaQueryWrapper<Product>().eq(Product::getCode, orderDetails.getCinvcode()));
//        for(SaleOrderProcess saleOrderProcess : processList){
//            ProcessPriceOrder priceOrder = iProcessPriceOrderService.getOne(new LambdaQueryWrapper<ProcessPriceOrder>()
//                    .eq(ProcessPriceOrder::getCustomerId, saleOrder.getCustomerCode())
//                    .eq(ProcessPriceOrder::getProductId, orderDetails.getCinvcode())
//                    .eq(ProcessPriceOrder::getType, orderDetails.getType())
//                    .eq(ProcessPriceOrder::getOrderProcessCode, saleOrderProcess.getOrderProcess()));
//
////            List<ProcessPriceProduce> priceProduceList = iProcessPriceProduceService.list(new LambdaQueryWrapper<ProcessPriceProduce>().eq(ProcessPriceProduce::getOrderId, priceOrder.getId()));
////            Set<String> codeSet = priceProduceList.stream().map(ProcessPriceProduce::getProduceProcessCode).collect(Collectors.toSet());
//            if(settlementOrderDetails.getSettlementType().equals(TypeEnum.exception_settlement.getCode())){
//                if(priceOrder.getPricingMethod().equals("计时")){
//                    List<SettlementOrderProcess> settlementOrderProcessList = iSettlementOrderProcessService.list(new LambdaQueryWrapper<SettlementOrderProcess>().eq(SettlementOrderProcess::getDetailsId, settleDetailId)
////                            .in(SettlementOrderProcess::getProductProcess, codeSet));
//                            .eq(SettlementOrderProcess::getProductProcess, saleOrderProcess.getOrderProcess()));
//                    BigDecimal totalExpectHours = settlementOrderProcessList.stream().map(SettlementOrderProcess::getExpectHours).reduce(BigDecimal.ZERO, BigDecimal::add);
////                    sum = sum.add(orderDetails.getSettlementQty().multiply(saleOrderProcess.getSettlementcost().multiply(totalExpectHours)));
//                    sum = sum.add(settlementOrderProcesses.get(0).getQty().multiply(saleOrderProcess.getSettlementcost().multiply(totalExpectHours)));
//                }else{
////                    sum = sum.add(orderDetails.getSettlementQty().multiply(saleOrderProcess.getSettlementcost()));
//                    sum = sum.add(settlementOrderProcesses.get(0).getQty().multiply(saleOrderProcess.getSettlementcost()));
//                }
//            }else{
//                if(priceOrder.getPricingMethod().equals("计时")){
////                    sum = sum.add(orderDetails.getSettlementQty().multiply(saleOrderProcess.getSettlementcost().multiply(priceOrder.getExpectHours())));
//                    sum = sum.add(settlementOrderProcesses.get(0).getQty().multiply(saleOrderProcess.getSettlementcost().multiply(priceOrder.getExpectHours())));
//                }else{
////                    sum = sum.add(orderDetails.getSettlementQty().multiply(saleOrderProcess.getSettlementcost()));
//                    sum = sum.add(settlementOrderProcesses.get(0).getQty().multiply(saleOrderProcess.getSettlementcost()));
//                }
//            }
//        }
//        orderDetails.setSettlementAmount((orderDetails.getSettlementAmount()==null?BigDecimal.ZERO:orderDetails.getSettlementAmount()).add(sum));
//        iSaleOrderDetailsService.updateById(orderDetails);
//
//        /**更新结算单明细表中结算状态、数量、金额*/
//        settlementOrderDetails.setCompletFlag(true);
//        settlementOrderDetails.setSettlementQty(settlementOrderProcesses.get(0).getQty());
//        settlementOrderDetails.setSettlementAmount(sum);
//        iSettlementOrderDetailsService.updateById(settlementOrderDetails);
//
//        /**结算单定价完成后，更新结算单结算状态*/
//        long c = iSettlementOrderDetailsService.count(new LambdaQueryWrapper<SettlementOrderDetails>().eq(SettlementOrderDetails::getMasterId, settlementOrder.getId())
//                .eq(SettlementOrderDetails::getCompletFlag, false));
//        if(c == 0){
//            settlementOrder.setStatus(true);
//            iSettlementOrderService.updateById(settlementOrder);
//        }
//
//        List<SaleOrderDetails> detailsList = iSaleOrderDetailsService.list(new LambdaQueryWrapper<SaleOrderDetails>().eq(SaleOrderDetails::getMasterId, saleOrder.getId()));
//        Set<Long> set = detailsList.stream().map(SaleOrderDetails::getId).collect(Collectors.toSet());
//        long count = iSettlementOrderDetailsService.count(new LambdaQueryWrapper<SettlementOrderDetails>().eq(SettlementOrderDetails::getMasterId, settlementOrder.getId())
//                .in(SettlementOrderDetails::getDetailId, set).eq(SettlementOrderDetails::getCompletFlag, false));
//        if(count == 0){
//            saleOrder.setStatus(true);
//            iSaleOrderService.updateById(saleOrder);
//            /**写入U8发货单*/
//            R result = generateU8dispatchList(settlementOrder, settlementOrderDetails.getSettlementQty(), settlementOrderDetails.getSettlementAmount());
//            if("500".equals(result.get("code").toString())){
//                throw new RuntimeException(result.get("msg").toString());
//            }
//        }
    }

    @Transactional
    public R generateU8somain(SaleOrder saleOrder) throws Exception{
        SomainParameter somainParameter = new SomainParameter();
        somainParameter.setOrderNo(saleOrder.getOrderNo());
        if(saleOrder.getCsocode() != null){
            somainParameter.setCsocode(saleOrder.getCsocode());
        }else{
            somainParameter.setCsocode("0000000001");
        }
        somainParameter.setCbustype("普通销售");
        somainParameter.setCstcode(saleOrder.getCstcode());
        if(saleOrder.getDdate() != null){
            somainParameter.setDdate(DateUtil.getDateFormat(saleOrder.getDdate()));
        }else{
            somainParameter.setDdate(new Date());
        }
        somainParameter.setCcuscode(saleOrder.getCustomerCode());
        somainParameter.setCdepcode(saleOrder.getCdepcode());
        if(saleOrder.getCexchName() != null){
            somainParameter.setCexch_name(saleOrder.getCexchName());
        }else{
            somainParameter.setCexch_name("人民币");
        }
        if(saleOrder.getPersonName() != null){
            somainParameter.setCpersoncode(saleOrder.getPersonName());
        }
        if(saleOrder.getIexchrate() != null){
            somainParameter.setIexchrate(saleOrder.getIexchrate());
        }else{
            somainParameter.setIexchrate("1");
        }
        if(saleOrder.getCmaker() != null){
            somainParameter.setCmaker(saleOrder.getCmaker());
        }else{
            somainParameter.setCmaker("api");
        }
        if(saleOrder.getCverifier() != null){
            somainParameter.setCverifier(saleOrder.getCverifier());
        }else{
            somainParameter.setCverifier("api");
        }
        if(saleOrder.getDverifydate() != null){
            somainParameter.setDverifydate(DateUtil.getDateFormat(saleOrder.getDdate()));
        }else{
            somainParameter.setDverifydate(new Date());
        }
        if(saleOrder.getDverifysystime() != null){
            somainParameter.setDverifysystime(DateUtil.getDateTimeFormat(saleOrder.getDdate()));
        }else{
            somainParameter.setDverifysystime(new Date());
        }
//        List<SaleOrderDetails> detailsList = iSaleOrderDetailsService.list(new LambdaQueryWrapper<SaleOrderDetails>().eq(SaleOrderDetails::getMasterId, saleOrder.getId()));
        List<SaleOrderDetails> detailsList = saleOrder.getDetailsList();
        List<SodetailsParameter> sodetailsParameterList = new ArrayList<>();
        for(SaleOrderDetails saleOrderDetails : detailsList){
            SodetailsParameter sodetailsParameter = new SodetailsParameter();
            sodetailsParameter.setDetailId(saleOrderDetails.getId().toString());
            sodetailsParameter.setCinvcode(saleOrderDetails.getCinvcode());
            sodetailsParameter.setIquantity(saleOrderDetails.getQty());
            Statement statement = null;
            ResultSet resultSet = null;
            try {
                String sql = "select cgroupcode " +
                        "from Inventory " +
                        "where cInvCode='"+saleOrderDetails.getCinvcode()+"'";
                statement = DataBaseConfig.connection.createStatement();
                resultSet = statement.executeQuery(sql);
                while (resultSet.next()){
                    sodetailsParameter.setCgroupcode(resultSet.getObject("cgroupcode").toString());
                }
            }catch (SQLException e){
                e.printStackTrace();
                return R.error("查询账套数据异常");
            }finally {
                try {
                    if(statement != null){
                        statement.close();
                    }
                    if(resultSet != null){
                        resultSet.close();
                    }
                }catch (SQLException e){
                    e.printStackTrace();
                }

            }
            sodetailsParameter.setDpredate(saleOrderDetails.getDpredate()==null?new Date():saleOrderDetails.getDpredate());
            sodetailsParameter.setDpremodate(saleOrderDetails.getDpremodate()==null?new Date():saleOrderDetails.getDpremodate());

            sodetailsParameter.setItaxrate(new BigDecimal(dispatchItaxrate));
            //含税单价
            BigDecimal itaxunitprice = saleOrderDetails.getAmount().divide(saleOrderDetails.getQty(),6, BigDecimal.ROUND_HALF_UP);
            sodetailsParameter.setItaxunitprice(itaxunitprice);
            //无税单价
            BigDecimal iunitprice = itaxunitprice.divide(BigDecimal.ONE.add(new BigDecimal(dispatchItaxrate).divide(new BigDecimal("100"))),6,BigDecimal.ROUND_HALF_UP);
            sodetailsParameter.setIunitprice(iunitprice);
            sodetailsParameter.setImoney(iunitprice.multiply(saleOrderDetails.getQty()));
            sodetailsParameter.setItax(saleOrderDetails.getAmount().subtract(iunitprice.multiply(saleOrderDetails.getQty())));
            sodetailsParameter.setIsum(saleOrderDetails.getAmount());
            sodetailsParameter.setInatunitprice(iunitprice);
            sodetailsParameter.setInatmoney(iunitprice.multiply(saleOrderDetails.getQty()));
            sodetailsParameter.setInattax(saleOrderDetails.getAmount().subtract(iunitprice.multiply(saleOrderDetails.getQty())));
            sodetailsParameter.setInatsum(saleOrderDetails.getAmount());
            sodetailsParameterList.add(sodetailsParameter);
        }
        somainParameter.setSodetailsParameterList(sodetailsParameterList);
        somainParameter.setEfserverid(serviceId);
        SaleOrderDetails orderDetails = detailsList.get(0);
        if(environment.equals("pro")){
            U8WebXMLResponseU8WebXMLResult u8WebXML = null;
            try {
                u8WebXML = eFWebServiceLocator.getEFWebServiceSoap().u8WebXML(SomainXml.createXML(somainParameter));
                //解析返回结果
                MessageElement[] data = u8WebXML.get_any();
                System.out.println(data[0].getAttribute("succeed").toString());
                System.out.println(data[0].getAttribute("dsc").toString());
                if("0".equals(data[0].getAttribute("succeed").toString())) {
                    return R.error("接口异常"+data[0].getAttribute("dsc").toString());
                }
                orderDetails.setErpId(data[0].getAttribute("retid").toString());
                orderDetails.setErpCode(data[0].getAttribute("retcode").toString());
                iSaleOrderDetailsService.updateById(orderDetails);
            }  catch (Exception e) {
                e.printStackTrace();
                return R.error("接口异常");
            }
        }else if(environment.equals("dev")){
            try {
                U8ApiResultDto resultDto = u8ApiUtils.httpRequest(SomainXml.createXML(somainParameter).split("\n")[1]);
                if(resultDto == null || "0".equals(resultDto.getCode())) {
                    return R.error(resultDto==null?"接口异常":resultDto.getMsg());
                }
                orderDetails.setErpId(resultDto.getRetid());
                orderDetails.setErpCode(resultDto.getRetcode());
                iSaleOrderDetailsService.updateById(orderDetails);
            }catch (Exception e){
                e.printStackTrace();
                return R.error("接口异常");
            }
        }
        return R.ok("写入成功");
    }

    @Transactional
    public R generateU8dispatchList(SaleOrder saleOrder, SettleOrderMasterNew settleOrderMasterNew) {
        DispatchListParameter dispatchListParameter = new DispatchListParameter();
        dispatchListParameter.setSettleId(settleOrderMasterNew.getId().toString());
        dispatchListParameter.setEfserverid(serviceId);
        dispatchListParameter.setCstcode(saleOrder.getCstcode());
        dispatchListParameter.setCdepcode(saleOrder.getCdepcode());
        dispatchListParameter.setCvouchtype("05");
        //销售订单号
        String cSoCode = null,cCusCode = null,cDepCode = null;
        List<Map<String, Object>> detailsList = new ArrayList<>();
        Statement statement = null;
        ResultSet resultSet = null;
        SaleOrderDetails saleOrderDetails = iSaleOrderDetailsService.getById(settleOrderMasterNew.getSaleOrderDetailId());
        try {
            String sql = "select cSoCode,cCusCode,cDepCode " +
                    "from SO_SOMain " +
                    "where ID="+saleOrderDetails.getErpId();
            statement = DataBaseConfig.connection.createStatement();
            resultSet = statement.executeQuery(sql);
            while (resultSet.next()){
                cSoCode = resultSet.getObject("cSoCode").toString();
                cCusCode = resultSet.getObject("cCusCode").toString();
                cDepCode = resultSet.getObject("cDepCode").toString();
            }
            sql = "select iSOsID,cInvCode " +
                    "from SO_SODetails " +
                    "where ID="+saleOrderDetails.getErpId();
            statement = DataBaseConfig.connection.createStatement();
            resultSet = statement.executeQuery(sql);
            while (resultSet.next()){
                Map<String, Object> map = new HashMap<>();
                map.put("AutoID", resultSet.getObject("iSOsID").toString());
                map.put("cInvCode", resultSet.getObject("cInvCode").toString());
                detailsList.add(map);
            }
        }catch (SQLException e){
            e.printStackTrace();
            return R.error("查询账套数据异常");
        }finally {
            try {
                if(statement != null){
                    statement.close();
                }
                if(resultSet != null){
                    resultSet.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }

        }
        dispatchListParameter.setCsocode(cSoCode);
        dispatchListParameter.setCcuscode(saleOrder.getCustomerCode());
        dispatchListParameter.setCexch_name("人民币");
        dispatchListParameter.setIexchrate("1");
        dispatchListParameter.setBreturnflag("0");
        dispatchListParameter.setCmaker("api");
        dispatchListParameter.setDdate(DateUtil.getDateFormat(settleOrderMasterNew.getSettleTime()));
        dispatchListParameter.setDcreatesystime(DateUtil.getDateFormat(settleOrderMasterNew.getSettleTime()));
        dispatchListParameter.setCverifier("api");
        dispatchListParameter.setDverifydate(DateUtil.getDateFormat(settleOrderMasterNew.getSettleTime()));
        dispatchListParameter.setDverifysystime(DateUtil.getDateFormat(settleOrderMasterNew.getSettleTime()));
        /**表体*/
        List<DispatchListsParameter> dispatchListsParameterList = new ArrayList<>();
        DispatchListsParameter dispatchListsParameter = new DispatchListsParameter();
        dispatchListsParameter.setCinvcode(settleOrderMasterNew.getCinvcode());
        Statement inventoryStatement = null;
        ResultSet inventoryResultSet = null;
        try {
            String sql = "select cgroupcode " +
                    "from Inventory " +
                    "where cInvCode='"+settleOrderMasterNew.getCinvcode()+"'";
            inventoryStatement = DataBaseConfig.connection.createStatement();
            inventoryResultSet = inventoryStatement.executeQuery(sql);
            while (inventoryResultSet.next()){
                dispatchListsParameter.setCgroupcode(inventoryResultSet.getObject("cgroupcode").toString());
            }
        }catch (SQLException e){
            e.printStackTrace();
            return R.error("查询账套数据异常");
        }finally {
            try {
                if(inventoryStatement != null){
                    inventoryStatement.close();
                }
                if(inventoryResultSet != null){
                    inventoryResultSet.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }

        }
        dispatchListsParameter.setIquantity(settleOrderMasterNew.getQty());
        dispatchListsParameter.setItaxrate(new BigDecimal(dispatchItaxrate));
        //含税单价
        BigDecimal itaxunitprice = settleOrderMasterNew.getAmount().divide(settleOrderMasterNew.getQty(),6, BigDecimal.ROUND_HALF_UP);
        dispatchListsParameter.setItaxunitprice(itaxunitprice);
        //无税单价
        BigDecimal iunitprice = itaxunitprice.divide(BigDecimal.ONE.add(new BigDecimal(dispatchItaxrate).divide(new BigDecimal("100"))),6,BigDecimal.ROUND_HALF_UP);
        dispatchListsParameter.setIunitprice(iunitprice);
        dispatchListsParameter.setImoney(iunitprice.multiply(settleOrderMasterNew.getQty()));
        dispatchListsParameter.setItax(settleOrderMasterNew.getAmount().subtract(iunitprice.multiply(settleOrderMasterNew.getQty())));
        dispatchListsParameter.setIsum(settleOrderMasterNew.getAmount());
        dispatchListsParameter.setInatunitprice(iunitprice);
        dispatchListsParameter.setInatmoney(iunitprice.multiply(settleOrderMasterNew.getQty()));
        dispatchListsParameter.setInattax(settleOrderMasterNew.getAmount().subtract(iunitprice.multiply(settleOrderMasterNew.getQty())));
        dispatchListsParameter.setInatsum(settleOrderMasterNew.getAmount());
        dispatchListsParameter.setCsocode(cSoCode);
        for (Map<String, Object> map : detailsList) {
            if(map.get("cInvCode").toString().equals(settleOrderMasterNew.getCinvcode())){
                String autoID = map.get("AutoID").toString();
                dispatchListsParameter.setIsosid(autoID);
                break;
            }
        }
        dispatchListsParameterList.add(dispatchListsParameter);
        dispatchListParameter.setDetailsList(dispatchListsParameterList);

        if(environment.equals("pro")){
            U8WebXMLResponseU8WebXMLResult u8WebXML = null;
            try {
                u8WebXML = eFWebServiceLocator.getEFWebServiceSoap().u8WebXML(DispatchListsXml.createXML(dispatchListParameter));
                //解析返回结果
                MessageElement[] data = u8WebXML.get_any();
                System.out.println(data[0].getAttribute("succeed").toString());
                System.out.println(data[0].getAttribute("dsc").toString());
                if("0".equals(data[0].getAttribute("succeed").toString())) {
                    return R.error("接口异常"+data[0].getAttribute("dsc").toString());
                }
                settleOrderMasterNew.setErpCode(data[0].getAttribute("retcode").toString());
                settleOrderMasterNew.setErpId(data[0].getAttribute("retid").toString());
            }  catch (Exception e) {
                e.printStackTrace();
                return R.error("接口异常");
            }
        }else if(environment.equals("dev")){
            dispatchListsParameter.setCwhcode("01");
            try {
                U8ApiResultDto resultDto = u8ApiUtils.httpRequest(DispatchListsXml.createXML(dispatchListParameter).split("\n")[1]);
                if(resultDto == null || "0".equals(resultDto.getCode())) {
                    return R.error(resultDto==null?"接口异常":resultDto.getMsg());
                }
                settleOrderMasterNew.setErpId(resultDto.getRetid());
                settleOrderMasterNew.setErpCode(resultDto.getRetcode());
            }catch (Exception e){
                e.printStackTrace();
                return R.error("接口异常");
            }
        }
        return R.ok("写入成功");
    }
}
